import UserService from '../service/user.service';
import { Inject, Provide } from '@midwayjs/decorator';
import { IWebMiddleware } from '@midwayjs/koa';
import { JWT_PREFIX, JWT_SECRET, TOKEN_EXPIRE  } from '../constants';
import * as moment from 'moment';
import { KWError } from '../common/error';
import { KWCode } from '../common/code';
import { TokenModel } from '../entity/token.entity';
import KWContext from '../common/context';

// auth 校验
@Provide('authorizationMiddleware')
export class AuthorizationMiddleware implements IWebMiddleware {

  @Inject('userService')
  userService: UserService;

  resolve() {
    return async (ctx: KWContext, next: any) => {
      const token = this.parseBearerToken(ctx);
      const tokenModel = await TokenModel.findOne({ token, secret: JWT_SECRET });
      const now = moment().unix();
      if (tokenModel && tokenModel.expires_in > now ) {
        const user = tokenModel.user;
        const userEntity = await this.userService.getUserById(user.uid);
        if (userEntity) {
          ctx.user = Object.assign({}, userEntity.toObject(), { token });
          await TokenModel.updateOne({ token }, { $set: { expires_in: now + TOKEN_EXPIRE }});
          return await next();
        } else {
          throw new KWError(KWCode.notFound, '用户不存在');
        }
      } else {
        throw new KWError(KWCode.unauthorized, '请登录');
      }
    }
  }

  private parseBearerToken(ctx: KWContext) {
    const auth = ctx.headers.authorization || ctx.request.body.authorization || ctx.request.query.authorization;
    if (!auth) {
      return null;
    }
    const parts = auth.split(' ');
    if (parts.length < 2) return null;
    const prefix = parts.shift().toLowerCase();
    if (prefix !== JWT_PREFIX) return null;
    const token = parts.shift();
    return token;
  }
}
